"""
Дополнительные компоненты для рабоыт плагина commands.
Функции для получения отображения и поиска по сипску комадн.

Author: Milinuri Nirvalen
Ver: 1.3 (7)
"""

from chiori import Chio

import re
import random

from typing import Optional
from typing import Dict
from collections import defaultdict

Plugins = Dict[str, dict]


def gen_lib(app: Chio) -> Plugins:
	"""Собирает словарь с данными о плагинах

	Args:
		app (Chio): Экзмепляр бота

	Returns:
		dict: словарь с данными о плагинах
	"""

	plugins_lib = {}
	for ap in app.plugins:
		# if ap.filename == 'main':
		# 	plugins_lib[ap.pid] = ap.__dict__
		# else:
		plugins_lib[ap.pid+":"+ap.filename] = ap.__dict__

	return plugins_lib


# Джижок поиска по командам
# =========================

def _get_mathes(k: str, v: dict, pattern: str) -> set[str]:
	mathes = set()

	if re.findall(pattern, k):
		mathes.add("pid")

	if re.findall(pattern, v.get("name", "None")):
		mathes.add("name")

	if re.findall(pattern, v.get("desc", "None")):
		mathes.add("desc")

	for x in v["check_funcs"]:
		if re.findall(pattern, x):
			mathes.add("ch-f")

	for p in v["routers"].values():
		if re.findall(pattern, p.get("usage", "None") or "None"):
			mathes.add("usage")

		for x in p["check_func"]:
			# TODO: выпилить эти проверяющие функции
			if re.findall(pattern, list(x)[0]):
				mathes.add("cmd_ch-f")

		for x in p["else_func"]:
			if re.findall(pattern, list(x)[0]):
				mathes.add("cmd_else-f")

		for x in p["cmds"]:
			if re.findall(pattern, x):
				mathes.add("cmd")

	return mathes

def search(lib: Plugins, pattern: str) -> str:
	grouped_res = defaultdict(set)
	for k, v in lib.items():
		mathes = _get_mathes(k, v, pattern)
		if len(mathes) > 0:


			grouped_res[", ".join(mathes)].add(k)

	text = f'🔎 результаты поиска "{pattern}":'
	for k, v in grouped_res.items():
		text += f"\n\n 🔶 {k} ({len(v)}):"

		for n in v:
			p = lib[n]

			# decor level
			if p.get("admins"):
				level = "🔥"
			elif p["commands"] > 3:
				level = "📦"
			else:
				level = ''

			text += f'\n-- {level} [{n}] {p.get("name")}'
	return text


def get_pid(lib: Plugins, pattern: str) -> list:
	res = []
	for k, v in lib.items():
		if re.findall(pattern, k):
			res.append(k)

		elif re.findall(pattern, v["name"]):
			res.append(k)

	return res


# Получение данных из списка команд
# =================================

def get_all_commands(lib: Plugins) -> list[dict]:
	res = []

	for p in lib.values():
		for v in p["routers"].values():
			res.append(v)

	return res

def get_all_names(lib: Plugins) -> dict[str]:
	res = {}

	for x in get_all_commands(lib):
		for n in x["cmds"]:
			res[n] = x

	return res

def get_random_cmd(lib: Plugins, commands: Optional[list]=None):
	if commands is None:
		commands = get_all_commands(lib)
	return random.choice(commands)
